package com.dongfanggroup.report.controller;

import cn.hutool.core.lang.Assert;
import cn.hutool.extra.pinyin.PinyinUtil;
import com.dongfanggroup.report.domain.ReportOrder;
import com.dongfanggroup.report.domain.ReportOrderHistory;
import com.dongfanggroup.report.domain.ReportTransferHistory;
import com.dongfanggroup.report.domain.req.*;
import com.dongfanggroup.report.enums.ReportOrderStatusEnum;
import com.dongfanggroup.report.service.IReportOrderHistoryService;
import com.dongfanggroup.report.service.IReportOrderService;
import com.dongfanggroup.report.service.IReportTransferHistoryService;
import com.google.common.collect.Lists;
import com.ruoyi.common.core.constant.Constants;
import com.ruoyi.common.core.domain.R;
import com.ruoyi.common.core.exception.ServiceException;
import com.ruoyi.common.core.utils.DateUtils;
import com.ruoyi.common.core.utils.StringUtils;
import com.ruoyi.common.core.utils.file.FileUtils;
import com.ruoyi.common.core.utils.poi.ExcelUtil;
import com.ruoyi.common.core.web.controller.BaseController;
import com.ruoyi.common.core.web.domain.AjaxResult;
import com.ruoyi.common.core.web.page.TableDataInfo;
import com.ruoyi.common.log.annotation.Log;
import com.ruoyi.common.log.enums.BusinessType;
import com.ruoyi.common.security.annotation.RequiresPermissions;
import com.ruoyi.common.security.utils.SecurityUtils;
import com.ruoyi.system.api.RemoteFileService;
import com.ruoyi.system.api.RemoteRoleService;
import com.ruoyi.system.api.RemoteUserService;
import com.ruoyi.system.api.domain.SysDept;
import com.ruoyi.system.api.domain.SysFile;
import com.ruoyi.system.api.domain.SysRole;
import com.ruoyi.system.api.domain.SysUser;
import com.ruoyi.system.api.model.LoginUser;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.annotations.Param;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

/**
 * 报障单Controller
 *
 * @author wangsr
 * @date 2021-12-16
 */
@RestController
@RequestMapping("/ReportOrder")
@Slf4j
public class ReportOrderController extends BaseController {
    @Autowired
    private IReportOrderService reportOrderService;

    @Autowired
    private IReportOrderHistoryService reportOrderHistoryService;

    @Autowired
    private RemoteUserService remoteUserService;

    @Autowired
    private RemoteRoleService remoteRoleService;
    @Autowired
    private IReportTransferHistoryService reportTransferHistoryService;

    @Autowired
    private RemoteFileService remoteFileService;


    /**
     * 查询报障单列表
     */
    @RequiresPermissions("report:ReportOrder:list")
    @GetMapping("/list")
    public TableDataInfo list(ReportOrderReq reportOrder) {
        startPage();
        List<ReportOrder> list = reportOrderService.selectReportOrderList(reportOrder);
        return getDataTable(list);
    }

    /**
     * 查询已提交报障单列表
     */
//    @RequiresPermissions("report:ReportOrder:list")
    @GetMapping("/listAllCreated")
    public TableDataInfo listAllCreated(ReportOrderReq reportOrder) {
        startPage();
        reportOrder.setReportStatus(Lists.newArrayList(ReportOrderStatusEnum.CREATE.getCode()));
        List<ReportOrder> list = reportOrderService.selectReportOrderList(reportOrder);
        return getDataTable(list);
    }

    /**
     * 查询我处理的报障列表
     */
    @GetMapping("/listMyOrder")
    public TableDataInfo listMyOrder(ReportOrderReq reportOrder) {
        startPage();
        reportOrder.setReportDealUserId(SecurityUtils.getUserId());
        List<ReportOrder> list = reportOrderService.selectReportOrderList(reportOrder);
        return getDataTable(list);
    }

    /**
     * 导出报障单列表
     */
    @RequiresPermissions("report:ReportOrder:export")
    @Log(title = "报障单", businessType = BusinessType.EXPORT)
    @PostMapping("/export")
    public void export(HttpServletResponse response, ReportOrderReq reportOrder) {
        List<ReportOrder> list = reportOrderService.selectReportOrderList(reportOrder);
        ExcelUtil<ReportOrder> util = new ExcelUtil<ReportOrder>(ReportOrder.class);
        util.exportExcel(response, list, "报障单数据");
    }

    /**
     * 获取报障单详细信息
     */
    @RequiresPermissions("report:ReportOrder:query")
    @GetMapping(value = "/{id}")
    public AjaxResult getInfo(@PathVariable("id") Long id) {
        ReportOrder reportOrder = reportOrderService.selectReportOrderById(id);
        checkDbOrder(reportOrder);
        return AjaxResult.success(reportOrder);
    }

    /**
     * 获取报障单详细信息
     */
//    @RequiresPermissions("report:ReportOrder:query")
    @GetMapping(value = "/noAuth/{id}")
    public AjaxResult getInfoNoAuth(@PathVariable("id") Long id) {
        return AjaxResult.success(reportOrderService.selectReportOrderById(id));
    }

    /**
     * 新增报障单
     */
    @RequiresPermissions("report:ReportOrder:add")
    @Log(title = "报障单", businessType = BusinessType.INSERT)
    @PostMapping
    @Transactional(rollbackFor = Exception.class)
    public AjaxResult add(@RequestBody ReportOrder reportOrder) {
        return toAjax(reportOrderService.insertReportOrder(reportOrder));
    }

    /**
     * 修改报障单
     */
    @RequiresPermissions("report:ReportOrder:edit")
    @Log(title = "报障单", businessType = BusinessType.UPDATE)
    @PutMapping
    public AjaxResult edit(@RequestBody ReportOrder reportOrder) {
        reportOrderHistoryService.insertNewLog(reportOrder.getId(), "修改报障单", ReportOrderStatusEnum.EDIT);
        return toAjax(reportOrderService.updateReportOrder(reportOrder));
    }

    /**
     * 删除报障单
     */
    @RequiresPermissions("report:ReportOrder:remove")
    @Log(title = "报障单", businessType = BusinessType.DELETE)
    @PostMapping("/del/{id}")
    public AjaxResult remove(@PathVariable Long id) {
        //先查询
        ReportOrder dbOrder = reportOrderService.selectReportOrderById(id);
        checkDbOrder(dbOrder);
        ReportOrder param = new ReportOrder();
        param.setId(dbOrder.getId());
        param.setReportStatus(ReportOrderStatusEnum.DELETED.getCode());
        reportOrderHistoryService.insertNewLog(id, "作废报障单", ReportOrderStatusEnum.DELETED);
        return toAjax(reportOrderService.updateReportOrder(param));
//        return toAjax(reportOrderService.deleteReportOrderByIds(ids));
    }


    @Log(title = "报障单撤回", businessType = BusinessType.UPDATE)
    @PostMapping("/back/{id}")
    public AjaxResult back(@PathVariable Long id) {

        //先查询
        ReportOrder dbOrder = reportOrderService.selectReportOrderById(id);
        checkDbOrder(dbOrder);
        if (!dbOrder.getReportStatus().equals(ReportOrderStatusEnum.CREATE.getCode())) {
            throw new ServiceException("当前状态不允许撤回，请刷新后重试");
        }
        ReportOrder param = new ReportOrder();
        param.setId(dbOrder.getId());
        param.setReportStatus(ReportOrderStatusEnum.EDIT.getCode());
        param.setReportSubmitTime(dbOrder.getCreateTime());
        reportOrderHistoryService.insertNewLog(id, "撤回报障单", ReportOrderStatusEnum.EDIT);
        return toAjax(reportOrderService.updateReportOrder(param));
    }

    @Log(title = "报障单接单", businessType = BusinessType.UPDATE)
    @PostMapping("/getOrder/{id}")
    @Transactional(rollbackFor = Exception.class)
    public AjaxResult getOrder(@PathVariable Long id) {
        ReportOrder reportOrder = reportOrderService.selectReportOrderById(id);
        //只有已提交(create)才能接单
        if (!ReportOrderStatusEnum.CREATE.getCode().equals(reportOrder.getReportStatus())) {
            throw new ServiceException("报障单状态不正确，请刷新后重试");
        }
        ReportOrder param = new ReportOrder();
        param.setId(reportOrder.getId());
        //设置开始时间为当前时间
        param.setReportTimeStart(DateUtils.getNowDate());
        param.setReportStatus(ReportOrderStatusEnum.DEALING.getCode());
        param.setReportDealUserId(SecurityUtils.getUserId());
        reportOrderHistoryService.insertNewLog(id, "报障单接单，开始处理", ReportOrderStatusEnum.EDIT);
        return toAjax(reportOrderService.updateReportOrder(param));
    }

    @Log(title = "报障单提交", businessType = BusinessType.UPDATE)
    @PostMapping("/submit/{id}")
    public AjaxResult submit(@PathVariable Long id) {

        //先查询
        ReportOrder dbOrder = reportOrderService.selectReportOrderById(id);
        checkDbOrder(dbOrder);
        if (!dbOrder.getReportStatus().equals(ReportOrderStatusEnum.EDIT.getCode())) {
            throw new ServiceException("当前状态不允许提交，请刷新后重试");
        }
        ReportOrder param = new ReportOrder();
        param.setId(dbOrder.getId());
        param.setReportStatus(ReportOrderStatusEnum.CREATE.getCode());
        param.setReportSubmitTime(DateUtils.getNowDate());
        reportOrderHistoryService.insertNewLog(id, "提交报障单", ReportOrderStatusEnum.CREATE);
        return toAjax(reportOrderService.updateReportOrder(param));
    }

    @Log(title = "报障单完成", businessType = BusinessType.UPDATE)
    @PostMapping("/complete")
    public AjaxResult complete(@RequestBody ReportCompleteReq reportCompleteReq) {

        //先查询
        ReportOrder dbOrder = reportOrderService.selectReportOrderById(reportCompleteReq.getId());
        if (dbOrder == null) {
            throw new ServiceException("报障单不存在");
        }
        if (!(dbOrder.getReportStatus().equals(ReportOrderStatusEnum.DEALING.getCode()) ||
                dbOrder.getReportStatus().equals(ReportOrderStatusEnum.BACKING.getCode()))) {
            throw new ServiceException("当前状态不允许处理，请刷新后重试");
        }
        ReportOrder param = new ReportOrder();
        param.setId(dbOrder.getId());
        param.setReportStatus(ReportOrderStatusEnum.COMPLETE.getCode());
        param.setReportReason(reportCompleteReq.getReportReason());
        param.setReportSolution(reportCompleteReq.getReportSolution());
        param.setReportTimeEnd(DateUtils.getNowDate());
        reportOrderHistoryService.insertNewLog(reportCompleteReq.getId(),
                String.format("报障单处理完毕！<br/>问题原因:%s<br/>解决方案:%s",
                        reportCompleteReq.getReportReason(),
                        reportCompleteReq.getReportSolution()),
                ReportOrderStatusEnum.COMPLETE);
        return toAjax(reportOrderService.updateReportOrder(param));
    }

    @Log(title = "重新打开报障单", businessType = BusinessType.UPDATE)
    @PostMapping("/reOpen")
    public AjaxResult reOpen(@RequestBody ReportReopenReq reportReopenReq) {

        //先查询
        ReportOrder dbOrder = reportOrderService.selectReportOrderById(reportReopenReq.getId());
        if (dbOrder == null) {
            throw new ServiceException("报障单不存在");
        }
        if (!dbOrder.getReportStatus().equals(ReportOrderStatusEnum.COMPLETE.getCode())) {
            throw new ServiceException("当前状态不允许重新打开，请刷新后重试");
        }
        ReportOrder param = new ReportOrder();
        param.setId(dbOrder.getId());
        param.setReportStatus(ReportOrderStatusEnum.BACKING.getCode());
        String reBackInfo = String.format("第%s次重新打开，原因:%s",
                dbOrder.getReportDealCount(),
                reportReopenReq.getReOpenInfo()
        );
        reportOrderHistoryService.insertNewLog(dbOrder.getId(),
                reBackInfo,
                ReportOrderStatusEnum.BACKING);
        param.setReportDealCount(dbOrder.getReportDealCount() + 1);
        param.setReportBackInfo(String.join("<br/>", Lists.newArrayList(dbOrder.getReportBackInfo(), reBackInfo)));
        return toAjax(reportOrderService.updateReportOrder(param));
    }

    @Log(title = "评价报障单", businessType = BusinessType.UPDATE)
    @PostMapping("/star")
    public AjaxResult star(@RequestBody ReportStarReq reportStarReq) {
        //先查询
        ReportOrder dbOrder = reportOrderService.selectReportOrderById(reportStarReq.getId());
        if (dbOrder == null) {
            throw new ServiceException("报障单不存在");
        }
        if (!dbOrder.getReportStatus().equals(ReportOrderStatusEnum.COMPLETE.getCode())) {
            throw new ServiceException("当前状态不允许评价，请刷新后重试");
        }
        ReportOrder param = new ReportOrder();
        param.setId(dbOrder.getId());
        param.setReportStatus(ReportOrderStatusEnum.STARED.getCode());
        param.setReportStarTime(DateUtils.getNowDate());
        param.setReportStar(reportStarReq.getStarValue());
        param.setReportStarInfo(reportStarReq.getStarInfo());
        String starInfo = String.format("评价完毕<br/>评分:%s<br/>评价:%s", reportStarReq.getStarValue(), reportStarReq.getStarInfo());
        reportOrderHistoryService.insertNewLog(dbOrder.getId(),
                starInfo,
                ReportOrderStatusEnum.STARED);
        return toAjax(reportOrderService.updateReportOrder(param));
    }

    private void checkDbOrder(ReportOrder dbOrder) {
        if (dbOrder == null) {
            throw new ServiceException("报障单不存在");
        }
        if (!dbOrder.getReportUserId().equals(SecurityUtils.getUserId())) {
            throw new ServiceException("非法请求，已记录");
        }
    }

    @GetMapping("/reportHistory/{reportId}")
    public AjaxResult reportHistory(@PathVariable Long reportId) {
        ReportOrder dbOrder = reportOrderService.selectReportOrderById(reportId);
        checkDbOrder(dbOrder);
        List<ReportOrderHistory> reportOrderHistories = reportOrderHistoryService.selectReportOrderHistoryByReportId(reportId);
        return AjaxResult.success(reportOrderHistories);
    }

    @GetMapping("/reportHistoryNoAuth/{reportId}")
    public AjaxResult reportHistoryNoAuth(@PathVariable Long reportId) {
        ReportOrder dbOrder = reportOrderService.selectReportOrderById(reportId);
        if (dbOrder == null) {
            throw new ServiceException("报障单不存在");
        }
        List<ReportOrderHistory> reportOrderHistories = reportOrderHistoryService.selectReportOrderHistoryByReportId(reportId);
        return AjaxResult.success(reportOrderHistories);
    }

    @PostMapping("/transferDealUser")
    public AjaxResult transferDealUser(@RequestBody ReportTransferReq transferReq) {
        ReportOrder dbOrder = reportOrderService.selectReportOrderById(transferReq.getId());
        if (dbOrder == null) {
            throw new ServiceException("报障单不存在");
        }
        String reportStatus = dbOrder.getReportStatus();
        ArrayList<String> status = Lists.newArrayList(ReportOrderStatusEnum.DEALING.getCode(), ReportOrderStatusEnum.BACKING.getCode());
        if (!status.contains(reportStatus)) {
            throw new ServiceException("当前状态不允许转移处理人，请刷新后重试");
        }

        ReportOrder param = new ReportOrder();
        param.setId(dbOrder.getId());
        param.setReportDealUserId(transferReq.getToUserId());
        R<SysUser> sysUserR = remoteUserService.getUserInfoById(transferReq.getToUserId(), "df-report");
//        SysUser user = userService.selectUserById(transferReq.getToUserId());
        if (sysUserR.getCode() != Constants.SUCCESS) {
            throw new ServiceException(sysUserR.getMsg());
        }
        SysUser user = sysUserR.getData();
        param.setReportDealUserName(user.getNickName());
        String transferInfo = String.format("转移处理人<br/>%s--->%s<br/>备注:%s", dbOrder.getReportDealUserName(), user.getNickName(), transferReq.getRemark());
        reportOrderHistoryService.insertNewLog(dbOrder.getId(),
                transferInfo,
                ReportOrderStatusEnum.DEALING);
        //添加转移历史
        ReportTransferHistory history = new ReportTransferHistory();
        history.setFromUserId(dbOrder.getReportDealUserId());
        history.setFromUserName(dbOrder.getReportDealUserName());
        history.setToUserId(user.getUserId());
        history.setToUserName(user.getNickName());
        history.setCreateBy(SecurityUtils.getUserId() + "");
        history.setReportId(dbOrder.getId());
        reportTransferHistoryService.insertReportTransferHistory(history);
        return toAjax(reportOrderService.updateReportOrder(param));
    }


    @GetMapping("/queryDealUser")
    public AjaxResult queryDealUser(@Param("query") String query) {
        SysRole param = new SysRole();
        param.setQueryScopeType(-1);
        List<SysRole> sysRoles = remoteRoleService.selectRoleList(param).getData();
        SysRole cardPerson = sysRoles.stream().filter(e -> e.getRoleKey().equals("reportDeal")).findFirst().orElse(null);
        Assert.notNull(cardPerson, "处理人查询为空");
        SysUser user = new SysUser();
        user.setRoleId(cardPerson.getRoleId());
        user.setQueryScopeType(-1);
        R<List<SysUser>> sysUsersR = remoteUserService.selectAllocatedList(user);
        if (sysUsersR.getCode() != Constants.SUCCESS) {
            throw new ServiceException(sysUsersR.getMsg());
        }
        List<SysUser> sysUsers = sysUsersR.getData();
        List<HashMap<String, Object>> collect = sysUsers.stream().filter(e -> {
            String userName = e.getUserName();
            String nickName = e.getNickName();
            String nickPinyin = PinyinUtil.getPinyin(e.getNickName());
            String nickPinyinTrim = nickPinyin.replace(" ", "");
            String deptName = Optional.ofNullable(e.getDept()).map(SysDept::getDeptName).get();
            SysDept dept = e.getDept();
            if (dept != null) {
                deptName = dept.getDeptName();
            }
            return userName.contains(query) || nickName.contains(query) || nickPinyin.contains(query) || nickPinyinTrim.contains(query)
                    || deptName.contains(query) || PinyinUtil.getPinyin(deptName).contains(query) || PinyinUtil.getPinyin(deptName).replace(" ", "").contains(query);
        }).map(e -> new HashMap<String, Object>() {{
            put("userId", e.getUserId());
            put("nameDept", e.getNickName() + "[" + Optional.ofNullable(e.getDept()).map(SysDept::getDeptName).get() + "]");
            put("userName", e.getNickName());
            put("deptId", e.getDeptId());
        }}).collect(Collectors.toList());
        return AjaxResult.success(collect);
    }

    /**
     * 头像上传
     */
    @PostMapping("/upload")
    public AjaxResult upload(@RequestParam("file") MultipartFile file) throws IOException {
        if (!file.isEmpty()) {
            R<SysFile> fileResult = remoteFileService.upload(file);
            if (StringUtils.isNull(fileResult) || StringUtils.isNull(fileResult.getData())) {
                return AjaxResult.error("文件服务异常，请联系管理员");
            }
            return AjaxResult.success(fileResult.getData());
        }
        return AjaxResult.error("上传图片异常，请联系管理员");
    }

}
